Advanced Graphics Assignment - Parametric surfaces
Matthew Dickinson - p1708355

The features of the submitted work are listed below in replacement of a demo session.
User controls are also listed in the console output window.

===========================
--Surface control points--
===========================

A 2D std::vector container holding a set of 4x4 control points can be found in main.cpp called ControlPts.

===================================
--Parametric surface calculation--
===================================

These control points are used within the main.cpp functions GenerateSurface(), GenerateSurfacePoint(), CalculateU() and CalculateV().

The functions used to generate the individual surface points are:
	-Bezier() for creating a bezier surface point.
	-UNR_Bspline() for creating a Uniform Non-Rational B-Spline surface point.

The surface is generated by using linear interpolation along U and V patch directions up to the desired level of detail/tesselation. 

CalculateU() obtains a position at u distance along the U direction. 
CalculateV() uses CalculateU() to generate a set of vertical control points. 

These control points at u distance calculate a position at v distance resulting in a 2D position using u,v.

The U,V coordinate used to generate a vertex is stored within its TexCoord attribute. This is later passed to the phong illumination vertex shader.

===================================================
--Converting surface points into a triangle mesh--
===================================================

GenerateSurfaceIndices() is utilised to convert the vertices stored in a 1D std::vector into a 2D triangle mesh representation. This is achieved using the levelOfDetail as an offset value to match vertices that are adjacent in 2D but not 1D.

The list of indices generated is then used in SceneObject.cpp's setUpGeometry(), DrawElements() and CalculateNormals() methods.

As the conversion uses the current levelOfDetail value, changing the value also changes the order of the indicies. As a result, tesselation adjustment can be done at runtime.

=======================
--Phong illumination--
=======================

The surface normals are calculated within SceneObject::CalculateNormals() using the adjacent vertices of each vertex, obtained from the indicies list. 
These indices are converted into triangles and added to a list of faces.
The normal to the face is then calculated using the cross product of the edges.

Method source: http://www.iquilezles.org/www/articles/normals/normals.htm

The phong shader uses the calculated normal to calculates the diffuse and speclar lighting components. These are added to the ambient component and used to alter the colour of the texture at the current TexCoord to generate the vertex colour.

=========================================
--Applying a 2D texture to the surface--
=========================================

The Texture is applied using opengl pipeline functions in SceneObject.cpp's LoadTexture() method. The texture .jpg is loaded using an implementation from "stb_image.h" source: https://github.com/nothings/stb

As mentioned above, the texCoords are obtained through the U,V interpolation process.

=============================================
--Control point manipulation functionality--
=============================================
The user can use the TAB key to switch between control points. The arrow keys can alter the selected control point's X and Y position while the PAGE_UP and PAGE_DOWN keys can alter the Z position. 

Once a control point is moved the surface vertices and normals are recalculated.

Pressing the SPACE key randomises the Z positions of all control points, allowing the user to see the effect on the surface curvature.

==========================
--Adjusting tesselation--
==========================

The level of triangle tesselation is adjusted by using the - and = keys to decrease and increase the level of detail/tesselation respectively.

Due to the CalculateSurfaceIndices() function, tesselation changes can take place in run-time as the indices are calculated based on the tesselation amount.

By pressing 2 the scene will switch to wireframe rendering allowing the user to better see the triangle tesselation as they adjust it using the - and = keys. 

The current levelOfDetail used by the control points is output to the console window.

==========================
--Extra Features--
==========================
By pressing 1 the control points will have lines drawn between them using wireframe triangles in an attempt to show the influence between control points.
 
By pressing 3 the parametric surface will switch from using Uniform Non-Rational B-splines to calculate surface points to using Bezier splines.

